using SmartLink.Domain.Entity;
using SmartLink.DTOS.Permission;
using SmartLink.EnumLibrary;
using SmartLink.Infrastructure.Cache;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartLink.Code
{
    /// <summary>
    /// 数据授权过滤器
    /// </summary>
    public class DataAuthorizeFilter
    {
        private int _userId;
        private ModuleCodeEnum _moduleCode;
        private IEnumerable<DataAuthorizationItemDTO> _moduleDataAuthorization;

        /// <summary>
        /// 构造当前用户和默认过滤规则的数据授权过滤器，使用此构造用户将不可配置过滤范围
        /// （默认过滤规则：超管，所有；公司管理员，根机构下所有；其他，当前机构）
        /// </summary>
        /// <param name="moduleCode">模块编码</param>
        public DataAuthorizeFilter()
        {
            _userId = CurrentUser.Current.UserId;
        }

        /// <summary>
        /// 构造当前用户和系统模块的数据授权过滤器
        /// </summary>
        /// <param name="moduleCode">模块编码</param>
        public DataAuthorizeFilter(ModuleCodeEnum moduleCode)
        {
            _userId = CurrentUser.Current.UserId;
            _moduleCode = moduleCode;
            Init();
        }

        /// <summary>
        /// 构造指定用户和系统模块的数据授权过滤器
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="moduleCode">模块编码</param>
        public DataAuthorizeFilter(int userId, ModuleCodeEnum moduleCode)
        {
            _userId = userId;
            _moduleCode = moduleCode;
            Init();
        }

        private void Init()
        {
            if (CurrentUser.IsSuperAdmin) return;
            if (CurrentUser.IsOrgAdmin) return;

            var rolePermissionsCache = RolePermissionCache.Get(CurrentUser.Current.RoleId);
            var roleModulePermissions = rolePermissionsCache.Where(a => a.Code.Equals(_moduleCode.ToString())).SingleOrDefault();
            if (roleModulePermissions != null)
            {
                _moduleDataAuthorization = roleModulePermissions.DataAuthorization;
            }
            else
            {
                throw new NullReferenceException($"当前角色没有相应模块的访问权限(ModuleCode：{_moduleCode.ToString()})");
            }
        }

        /// <summary>
        /// 对源查询SQL进行数据权限过滤包装（源SQL根据业务需要提供 Creator、OID、ODID 一列或多列字段），OID必须要有
        /// </summary>
        /// <param name="sourceSql">源查询SQL</param>
        /// <returns>包装</returns>
        public string WrapSql(string sourceSql)
        {
            StringBuilder wrapperSb = new StringBuilder(" SELECT * FROM (");
            wrapperSb.Append(sourceSql);
            wrapperSb.Append(") _temp_wrapper ");
            wrapperSb.Append(" WHERE 1<>1 ");

            if (CurrentUser.IsSuperAdmin)
            {
                wrapperSb.Append(" OR 1=1 ");
            }
            else if (CurrentUser.IsOrgAdmin)
            {
                wrapperSb.Append($" OR FIND_IN_SET(OID, '{string.Join(",", CurrentUser.Current.RootOrgDescendantsIds)}')>0 ");
            }
            else
            {
                if (_moduleDataAuthorization != null && _moduleDataAuthorization.Count() > 0)
                {
                    foreach (var item in _moduleDataAuthorization)
                    {
                        switch (item.AuthorizationScope)
                        {
                            case AuthorizationScopeEnum.Root:
                                wrapperSb.Append($" OR FIND_IN_SET(OID, '{string.Join(",", CurrentUser.Current.RootOrgDescendantsIds)}')>0 ");
                                break;
                            case AuthorizationScopeEnum.Self:
                                wrapperSb.Append($" OR Creator = {_userId} ");
                                break;
                            case AuthorizationScopeEnum.Department:
                                wrapperSb.Append($" OR ODID IN (SELECT OD_ID FROM BIZ_UserToOrganization WHERE UserID={_userId}) ");
                                break;
                            case AuthorizationScopeEnum.Organization:
                                wrapperSb.Append($" OR OID IN (SELECT OID FROM BIZ_UserToOrganization WHERE UserID={_userId}) ");
                                break;
                            case AuthorizationScopeEnum.CustomDepartment:
                                if (item.CustomResourseIds != null && item.CustomResourseIds.Count > 0)
                                {
                                    foreach (int customResourseId in item.CustomResourseIds)
                                    {
                                        wrapperSb.Append($" OR ODID={customResourseId} ");
                                    }
                                }
                                break;
                            case AuthorizationScopeEnum.CustomOrganization:
                                if (item.CustomResourseIds != null && item.CustomResourseIds.Count > 0)
                                {
                                    foreach (int customResourseId in item.CustomResourseIds)
                                    {
                                        wrapperSb.Append($" OR OID={customResourseId} ");
                                    }
                                }
                                break;
                        }
                    }
                }
                else
                {
                    //默认仅当前机构
                    wrapperSb.Append($" OR OID IN (SELECT OID FROM BIZ_UserToOrganization WHERE UserID={_userId}) ");
                }
            }
            //没配数据权限执行源Sql默认范围逻辑
            return wrapperSb.ToString();
        }
    }
}
